package br.ufrj.ppgi.infovis.forms;

import org.mt4j.AbstractMTApplication;
import org.mt4j.components.visibleComponents.shapes.MTRectangle;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;

import processing.core.PApplet;

public abstract class AbstractOverlay extends MTRectangle {

    /* *** Overlay constants *** */
    /**
     * The desired offset from the border that adds to the maximum/minimum
     * position the overlay can be positioned at.
     */
    protected static final float CHECK_BORDER_OFFSET = 0;

    /* *** Application *** */
    /** The multitouch application instance */
    AbstractMTApplication        mtApplication;

    /* ***********Constructors*********** */
    /**
     * Constructor. Instantiates a new AbstractOverlay
     * 
     * @param pApplet
     *            the application instance
     * @param x
     *            the x position of the overlay
     * @param y
     *            the y position of the overlay
     * @param width
     *            the width of the overlay
     * @param height
     *            the height of the overlay
     */
    public AbstractOverlay(PApplet pApplet, float x, float y, float width, float height) {
        super(pApplet, x, y, width, height);
        // Set app reference and fonts
        this.mtApplication = (AbstractMTApplication) pApplet;
        // Initialize
        initialize();
    }

    /* **********Object methods********** */
    /**
     * Initializes a new AbstractOverlay
     * 
     */
    private void initialize() {
        // Remove scaling processor and listener
        ToolsEventHandling.removeScaleProcessorsAndListeners(this);
        // Set custom drag listener
        addCustomDragListener();
        // Set custom rotate listener
        addCustomRotateListener();
    }

    /**
     * Adds a custom drag listener that prevents dragging the overlay beyond the
     * screen borders.
     * 
     */
    private void addCustomDragListener() {
    	// Remove default drag processor and listeners
        ToolsEventHandling.removeDragProcessorsAndListeners(this);
        // Add new modified drag processor
        this.registerInputProcessor(new DragProcessor(this.mtApplication));
        this.addGestureListener(DragProcessor.class, new DragActionCheckBorders(this.mtApplication, CHECK_BORDER_OFFSET));
    }

    /**
     * Adds a custom rotate listener that prevents dragging the overlay beyond
     * the screen borders through rotating.
     * 
     */
    private void addCustomRotateListener() {
        // Remove default rotate processors and listeners
        ToolsEventHandling.removeRotateProcessorsAndListeners(this);
        // Add new modified rotate processor
        this.registerInputProcessor(new RotateProcessor(this.mtApplication));
        this.addGestureListener(RotateProcessor.class, new RotateActionCheckBorders(this.mtApplication, CHECK_BORDER_OFFSET));
    }
}
